using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.Reflection;
using System.Text.RegularExpressions;
using System.IO;
using ionic.utils.zip;

namespace StartMenuSearcher
{
	public class Updater
	{
		public void CheckForUpdates()
		{
			Thread updateThread = new Thread(new ThreadStart(Run));
			updateThread.Priority = ThreadPriority.BelowNormal;
			updateThread.Start();
		}

		private void Run()
		{
			try
			{
				string newestVersion = GetUpdateToVersion();
				if (newestVersion == null)
					return;

				if (ShouldUpdate(newestVersion))
				{
					DownloadNewVersion(newestVersion);
				}
			}
			catch (Exception)
			{
				//eh.  Something happened.  This isn't an essential part of the program,
				//so let's just sliently ignore the error and let the thread end.
			}
		}

		private string GetUpdateToVersion()
		{
			WebClient client = new WebClient();

			//Get the page telling us if an update is out
			string updateInfo = client.DownloadString(Properties.Resources.AutoUpdateUrl);

			Regex versionRegex = new Regex(Properties.Resources.AutoUpdateSearchString);
			Match match = versionRegex.Match(updateInfo);

			if (match.Groups.Count < 2)
				return null;

			return match.Groups[1].Value;
		}

		private bool ShouldUpdate(string newestVersion)
		{
			string currentVersion = GetAssemblyVersion();

			int[] newVersionNums = ToIntArray(newestVersion.Split('.'));
			int[] curVersionNums = ToIntArray(currentVersion.Split('.'));

			for (int i = 0; i < Math.Min(newVersionNums.Length, curVersionNums.Length); i++)
			{
				if (newVersionNums[i] > curVersionNums[i])
					return true;
				if (newVersionNums[i] < curVersionNums[i])
					return false;
			}

			return false;
		}

		private void DownloadNewVersion(string version)
		{
			WebClient client = new WebClient();
			string downloadUri = string.Format(Properties.Resources.FileDownloadUrl, version);
			client.DownloadFile(downloadUri, Properties.Resources.DownloadedFileName);

			using (ZipFile zip = ZipFile.Read(Properties.Resources.DownloadedFileName))
			{
				string updateFolder = Path.GetFullPath("Update");
				foreach (ZipEntry entry in zip)
				{
					if (entry.FileName != "StartMenuSearcher.exe")
						entry.Extract(updateFolder);
				}
			}

			File.Delete(Properties.Resources.DownloadedFileName);
		}

		private int[] ToIntArray(string[] strArray)
		{
			int[] ret = new int[strArray.Length];
			for (int i = 0; i < ret.Length; i++)
				ret[i] = int.Parse(strArray[i]);
			return ret;
		}

		private string GetAssemblyVersion()
		{
			return Assembly.GetExecutingAssembly().GetName().Version.ToString();
		}
	}
}
